import type { IStudentState } from './studentStore';
import { StudentStatusEnum } from '@/types/student/enums';
import type { IStudent } from '@/types/student/student';

/**
 * 学生选择器函数
 * @description 提供各种学生数据的选择和计算函数
 */
export const studentSelectors = {
  /**
   * 获取所有学生
   * @param state 学生状态
   * @returns 所有学生列表
   */
  getAllStudents: (state: IStudentState): IStudent[] => state.students,

  /**
   * 获取活跃学生（在读状态）
   * @param state 学生状态
   * @returns 活跃学生列表
   */
  getActiveStudents: (state: IStudentState): IStudent[] => 
    state.students.filter(student => student.status === StudentStatusEnum.ACTIVE),

  /**
   * 获取休学学生
   * @param state 学生状态
   * @returns 休学学生列表
   */
  getInactiveStudents: (state: IStudentState): IStudent[] => 
    state.students.filter(student => student.status === StudentStatusEnum.INACTIVE),

  /**
   * 获取毕业学生
   * @param state 学生状态
   * @returns 毕业学生列表
   */
  getGraduatedStudents: (state: IStudentState): IStudent[] => 
    state.students.filter(student => student.status === StudentStatusEnum.GRADUATED),

  /**
   * 根据ID获取学生
   * @param state 学生状态
   * @param id 学生ID
   * @returns 学生信息或undefined
   */
  getStudentById: (state: IStudentState, id: string): IStudent | undefined => 
    state.students.find(student => student.id === id),

  /**
   * 根据学号获取学生
   * @param state 学生状态
   * @param studentId 学号
   * @returns 学生信息或undefined
   */
  getStudentByStudentId: (state: IStudentState, studentId: string): IStudent | undefined => 
    state.students.find(student => student.studentId === studentId),

  /**
   * 根据年级获取学生
   * @param state 学生状态
   * @param grade 年级
   * @returns 该年级的学生列表
   */
  getStudentsByGrade: (state: IStudentState, grade: string): IStudent[] => 
    state.students.filter(student => student.grade === grade),

  /**
   * 根据班级获取学生
   * @param state 学生状态
   * @param className 班级名称
   * @returns 该班级的学生列表
   */
  getStudentsByClass: (state: IStudentState, className: string): IStudent[] => 
    state.students.filter(student => student.class === className),

  /**
   * 根据性别获取学生
   * @param state 学生状态
   * @param gender 性别
   * @returns 该性别的学生列表
   */
  getStudentsByGender: (state: IStudentState, gender: 'male' | 'female' | 'other'): IStudent[] => 
    state.students.filter(student => student.gender === gender),

  /**
   * 获取筛选后的学生列表
   * @param state 学生状态
   * @returns 筛选后的学生列表
   */
  getFilteredStudents: (state: IStudentState): IStudent[] => {
    let filtered = state.students;

    // 应用筛选条件
    if (state.filters.filters.grade) {
      filtered = filtered.filter(student => student.grade === state.filters.filters.grade);
    }

    if (state.filters.filters.class) {
      filtered = filtered.filter(student => student.class === state.filters.filters.class);
    }

    if (state.filters.filters.status !== undefined) {
      filtered = filtered.filter(student => student.status === state.filters.filters.status);
    }

    if (state.filters.filters.gender) {
      filtered = filtered.filter(student => student.gender === state.filters.filters.gender);
    }

    // 应用搜索关键词
    if (state.filters.searchKeyword) {
      const keyword = state.filters.searchKeyword.toLowerCase();
      filtered = filtered.filter(student => 
        student.name.toLowerCase().includes(keyword) ||
        student.studentId.toLowerCase().includes(keyword) ||
        (student.phone && student.phone.includes(keyword)) ||
        (student.parentName && student.parentName.toLowerCase().includes(keyword)) ||
        (student.grade && student.grade.toLowerCase().includes(keyword)) ||
        (student.class && student.class.toLowerCase().includes(keyword))
      );
    }

    // 应用排序
    if (state.filters.sortBy) {
      filtered.sort((a, b) => {
        const aValue = a[state.filters.sortBy as keyof IStudent] as string;
        const bValue = b[state.filters.sortBy as keyof IStudent] as string;
        
        if (!aValue && !bValue) return 0;
        if (!aValue) return 1;
        if (!bValue) return -1;
        
        const comparison = aValue.localeCompare(bValue);
        return state.filters.sortOrder === 'asc' ? comparison : -comparison;
      });
    }

    return filtered;
  },

  /**
   * 获取选中的学生列表
   * @param state 学生状态
   * @returns 选中的学生列表
   */
  getSelectedStudents: (state: IStudentState): IStudent[] => 
    state.students.filter(student => state.selectedStudentIds.includes(student.id)),

  /**
   * 获取所有年级列表
   * @param state 学生状态
   * @returns 年级列表（去重）
   */
  getAllGrades: (state: IStudentState): string[] => {
    const grades = state.students
      .map(student => student.grade)
      .filter((grade): grade is string => Boolean(grade));
    return Array.from(new Set(grades)).sort();
  },

  /**
   * 获取所有班级列表
   * @param state 学生状态
   * @returns 班级列表（去重）
   */
  getAllClasses: (state: IStudentState): string[] => {
    const classes = state.students
      .map(student => student.class)
      .filter((className): className is string => Boolean(className));
    return Array.from(new Set(classes)).sort();
  },

  /**
   * 获取学生统计信息
   * @param state 学生状态
   * @returns 统计信息
   */
  getStudentStatistics: (state: IStudentState) => {
    const students = state.students;
    const totalCount = students.length;
    const activeCount = students.filter(s => s.status === StudentStatusEnum.ACTIVE).length;
    const inactiveCount = students.filter(s => s.status === StudentStatusEnum.INACTIVE).length;
    const graduatedCount = students.filter(s => s.status === StudentStatusEnum.GRADUATED).length;

    // 年级分布
    const gradeMap = new Map<string, number>();
    students.forEach(student => {
      if (student.grade) {
        gradeMap.set(student.grade, (gradeMap.get(student.grade) || 0) + 1);
      }
    });
    const gradeDistribution = Array.from(gradeMap.entries()).map(([grade, count]) => ({
      grade,
      count
    }));

    // 班级分布
    const classMap = new Map<string, number>();
    students.forEach(student => {
      if (student.class) {
        classMap.set(student.class, (classMap.get(student.class) || 0) + 1);
      }
    });
    const classDistribution = Array.from(classMap.entries()).map(([className, count]) => ({
      class: className,
      count
    }));

    // 性别分布
    const genderMap = new Map<'male' | 'female' | 'other', number>();
    students.forEach(student => {
      if (student.gender) {
        genderMap.set(student.gender, (genderMap.get(student.gender) || 0) + 1);
      }
    });
    const genderDistribution = Array.from(genderMap.entries()).map(([gender, count]) => ({
      gender,
      count
    }));

    return {
      totalCount,
      activeCount,
      inactiveCount,
      graduatedCount,
      gradeDistribution,
      classDistribution,
      genderDistribution
    };
  },

  /**
   * 检查是否有加载中的操作
   * @param state 学生状态
   * @returns 是否正在加载
   */
  isLoading: (state: IStudentState): boolean => state.async.loading,

  /**
   * 获取错误信息
   * @param state 学生状态
   * @returns 错误信息
   */
  getError: (state: IStudentState): string | null => state.async.error,

  /**
   * 获取最后更新时间
   * @param state 学生状态
   * @returns 最后更新时间戳
   */
  getLastUpdated: (state: IStudentState): number | null => state.async.lastUpdated,

  /**
   * 检查是否有选中的学生
   * @param state 学生状态
   * @returns 是否有选中的学生
   */
  hasSelectedStudents: (state: IStudentState): boolean => state.selectedStudentIds.length > 0,

  /**
   * 检查是否全选
   * @param state 学生状态
   * @returns 是否全选
   */
  isAllSelected: (state: IStudentState): boolean => {
    const filteredStudents = studentSelectors.getFilteredStudents(state);
    return filteredStudents.length > 0 && 
           filteredStudents.every(student => state.selectedStudentIds.includes(student.id));
  },

  /**
   * 检查是否部分选中
   * @param state 学生状态
   * @returns 是否部分选中
   */
  isIndeterminate: (state: IStudentState): boolean => {
    const filteredStudents = studentSelectors.getFilteredStudents(state);
    const selectedCount = filteredStudents.filter(student => 
      state.selectedStudentIds.includes(student.id)
    ).length;
    return selectedCount > 0 && selectedCount < filteredStudents.length;
  },

  /**
   * 获取选中学生数量
   * @param state 学生状态
   * @returns 选中学生数量
   */
  getSelectedCount: (state: IStudentState): number => state.selectedStudentIds.length,

  /**
   * 检查学生是否被选中
   * @param state 学生状态
   * @param studentId 学生ID
   * @returns 是否被选中
   */
  isStudentSelected: (state: IStudentState, studentId: string): boolean => 
    state.selectedStudentIds.includes(studentId)
};